#include "trap.h"
#include "instr_def.h"

#define ADD_TEST(rs, rt, rd) \
    ADD(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define ADDI_TEST(rs, rt, imm) \
    ADDI(rs, imm); \
    li $s2, rt; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define ADDU_TEST(rs, rt, rd) \
    ADDU(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define ADDIU_TEST(rs, rt, imm) \
    ADDIU(rs, imm); \
    li $s2, rt; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define SUB_TEST(rs, rt, rd) \
    SUB(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define SUBU_TEST(rs, rt, rd) \
    SUBU(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define SLT_TEST(rs, rt, rd) \
    SLT(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define SLTI_TEST(rs, rt, imm) \
    SLTI(rs, imm); \
    li $s2, rt; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define SLTU_TEST(rs, rt, rd) \
    SLTU(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define SLTIU_TEST(rs, rt, imm) \
    SLTIU(rs, imm); \
    li $s2, rt; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define MULT_TEST(rs, rt, hi, lo) \
    MULT(rs, rt); \
    li $s2, hi; \
    mfhi $s0; \
    bne $s0, $s2, res_error; \
    nop; \
    li $s2, lo; \
    mflo $s0; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define MULTU_TEST(rs, rt, hi, lo) \
    MULTU(rs, rt); \
    li $s2, hi; \
    mfhi $s0; \
    bne $s0, $s2, res_error; \
    nop; \
    nop; \
    li $s2, lo; \
    mflo $s0; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define DIV_TEST(rs, rt, hi, lo) \
    DIV(rs, rt); \
    li $s2, hi; \
    mfhi $s0; \
    bne $s0, $s2, res_error; \
    nop; \
    nop; \
    li $s2, lo; \
    mflo $s0; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define DIVU_TEST(rs, rt, hi, lo) \
    DIVU(rs, rt); \
    li $s2, hi; \
    mfhi $s0; \
    bne $s0, $s2, res_error; \
    nop; \
    li $s2, lo; \
    mflo $s0; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define AND_TEST(rs, rt, rd) \
    AND(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define ANDI_TEST(rs, rt, imm) \
    ANDI(rs, imm); \
    li $s2, rt; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define LUI_TEST(rt, imm) \
    LUI(imm); \
    li $s2, rt; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define NOR_TEST(rs, rt, rd) \
    NOR(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define OR_TEST(rs, rt, rd) \
    OR(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define ORI_TEST(rs, rt, imm) \
    ORI(rs, imm); \
    li $s2, rt; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define XOR_TEST(rs, rt, rd) \
    XOR(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define XORI_TEST(rs, rt, imm) \
    XORI(rs, imm); \
    li $s2, rt; \
    bne $s0, $s2, res_error;\
    li $s0, 0;
    
#define SLLV_TEST(rs, rt, rd) \
    SLLV(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define SLL_TEST(rt, rd, sa) \
    SLL(rt, sa); \
    li $s2, rd; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define SRLV_TEST(rs, rt, rd) \
    SRLV(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define SRL_TEST(rt, rd, sa) \
    SRL(rt, sa); \
    li $s2, rd; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define SRAV_TEST(rs, rt, rd) \
    SRAV(rs, rt); \
    li $s2, rd; \
    bne $s0, $s2, res_error;\
    li $s0, 0;

#define SRA_TEST(rt, rd, sa) \
    SRA(rt, sa); \
    li $s2, rd; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define HI_TEST(rs, rd) \
    MTHI(rs); \
    nop; \
    nop; \
    li $s2, rd; \
    MFHI(); \
    nop; \
    nop; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define LO_TEST(rs, rd) \
    MTLO(rs); \
    nop; \
    nop; \
    li $s2, rd; \
    MFLO(); \
    nop; \
    nop; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define SLB_TEST(data, base, offset) \
    LB(base, offset); \
    li $s2, data; \
    nop; \
    nop; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define SLH_TEST(data, base, offset) \
    LH(base, offset); \
    li $s2, data; \
    nop; \
    nop; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define SLW_TEST(data, base, offset) \
    LW(base, offset); \
    li $s2, data; \
    nop; \
    nop; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define LBU_TEST(data, base, offset) \
    LBU(base, offset); \
    li $s2, data; \
    nop; \
    nop; \
    bne $s0, $s2, res_error; \
    li $s0, 0;

#define LHU_TEST(data, base, offset) \
    LHU(base, offset); \
    li $s2, data; \
    nop; \
    nop; \
    bne $s0, $s2, res_error; \
    li $s0, 0; 


